البحث في DOM عبر *getElement و *querySelector في جافاسكربت
تُعد عملية التفاعل مع عناصر الصفحة الإلكترونية من أهم المهام التي يقوم بها مطورو الويب من خلال لغة جافاسكربت. ومن أجل التلاعب بمحتويات الصفحة أو تحديثها أو استخراج بيانات منها، يحتاج المطورون إلى آليات فعالة وسريعة للوصول إلى عناصر DOM (Document Object Model) بكل سهولة ودقة. في هذا المقال، سنغوص عميقاً في طرق البحث عن عناصر DOM باستخدام دوال *getElement و *querySelector المتاحة في جافاسكربت، مع شرح تفصيلي لأوجه الاختلاف بينهما، كيفية استخدامها، وأفضل الممارسات لتحقيق أداء عالٍ وسهولة في الصيانة.
مفهوم DOM وأهمية البحث فيه
DOM هو تمثيل هيكلي لشجرة عناصر صفحة الويب، حيث يمثل كل عنصر فيها (كالوسوم tags والنصوص والخصائص) ككائن يمكن التفاعل معه برمجياً. تتيح جافاسكربت عبر DOM التحكم الكامل في الصفحة، من حيث تعديل النصوص، تغيير خصائص العناصر، إضافة أو حذف عناصر، وغيرها من التفاعلات الديناميكية.
وبالتالي، فإن القدرة على البحث الدقيق والسريع عن العناصر ضمن هذه الشجرة هو أمر أساسي لتحقيق هذه المهام.
الفرق بين دوال *getElement و *querySelector
هناك عدة طرق للبحث عن عناصر DOM، وأشهرها:
-
دوال getElement:
-
getElementById -
getElementsByClassName -
getElementsByTagName
-
-
دوال querySelector و querySelectorAll
1. getElementById
تُستخدم هذه الدالة للبحث عن عنصر واحد فقط بواسطة معرفه الفريد id. هذه الدالة تعود بكائن العنصر مباشرة أو بـ null إذا لم يكن موجوداً.
مثال:
javascriptconst element = document.getElementById('header');
مميزاتها:
-
سريعة لأنها تبحث عن عنصر وحيد محدد.
-
لا تعيد مجموعة بل عنصر واحد فقط.
2. getElementsByClassName
تبحث عن جميع العناصر التي تحمل صنفاً معيناً (class) وتعيد مجموعة حية (HTMLCollection) من العناصر.
مثال:
javascriptconst items = document.getElementsByClassName('menu-item');
مميزات:
-
تعيد مجموعة يمكن التكرار عليها.
-
المجموعة حية، أي أنها تعكس التغييرات التي تطرأ على DOM في الوقت الحقيقي.
3. getElementsByTagName
تُعيد جميع العناصر التي تحمل وسمًا معينًا في الصفحة، كمجموعة حية أيضًا.
مثال:
javascriptconst paragraphs = document.getElementsByTagName('p');
4. querySelector
هذه الدالة الأكثر مرونة وتستخدم لاستعلام عن أول عنصر في DOM يطابق محدد CSS معين. تُعيد العنصر أو null إذا لم يُعثر على شيء.
مثال:
javascriptconst firstButton = document.querySelector('button.primary');
5. querySelectorAll
تعيد جميع العناصر المطابقة للمحدد CSS كـ مجموعة ثابتة (NodeList).
مثال:
javascriptconst allLinks = document.querySelectorAll('a.external');
المقارنة التفصيلية بين دوال getElement و querySelector
| الخاصية | getElementById | getElementsByClassName / TagName | querySelector | querySelectorAll |
|---|---|---|---|---|
| نوع البحث | عن طريق id فقط |
عن طريق class أو اسم الوسم (tag) |
بواسطة محدد CSS (مثل: .class, #id, tag) |
بواسطة محدد CSS متعدد |
| النتيجة | عنصر واحد أو null |
مجموعة حية (HTMLCollection) | عنصر واحد أو null |
مجموعة ثابتة (NodeList) |
| قابلية التكرار على النتيجة | لا | نعم | لا | نعم |
| نوع المجموعة | غير قابلة للتكرار (عنصر وحيد) | حية (تنعكس التعديلات الحية في DOM عليها) | غير قابلة للتكرار (عنصر وحيد) | ثابتة (لا تتغير مع تغييرات DOM) |
| دعم محددات CSS | لا | لا | نعم | نعم |
| الأداء | أفضل في البحث عن عنصر بواسطة id | جيد عند البحث عن عناصر بحسب class أو tag | أبطأ قليلاً بسبب تحليل CSS Selector | أبطأ قليلاً |
| متى تستخدم | عند الحاجة للوصول إلى عنصر معرف بـ id فريد | عند البحث عن مجموعة عناصر متشابهة بسرعة | عند الحاجة لاستعلام معقد أو مركب | عند الحاجة لجلب كل العناصر المطابقة لمحدد CSS |
استخدامات عملية ومقارنة تطبيقية
البحث بواسطة id
id هو معرف فريد من نوعه في الصفحة، لذلك getElementById هو الاختيار الأفضل والأسرع للوصول إلى عنصر معين بسرعة.
javascriptconst mainTitle = document.getElementById('main-title');
mainTitle.textContent = 'مرحباً بالعالم!';
البحث بواسطة class
عندما تكون هناك عدة عناصر تشترك في نفس الصنف، يمكننا استخدام getElementsByClassName أو querySelectorAll.
javascriptconst buttons = document.getElementsByClassName('btn');
for(let btn of buttons) {
btn.style.color = 'red';
}
أو باستخدام querySelectorAll:
javascriptconst buttons = document.querySelectorAll('.btn');
buttons.forEach(btn => btn.style.color = 'red');
البحث بواسطة محدد CSS مع تعقيد أعلى
باستخدام querySelector يمكن البحث ضمن عناصر معينة أو بناء محددات أكثر دقة مثل:
javascriptconst firstActiveButton = document.querySelector('button.active.primary');
الفرق في التفاعل مع النتائج
-
المجموعة الحية (HTMLCollection) تتغير تلقائياً مع تغييرات DOM:
javascriptconst items = document.getElementsByClassName('item');
console.log(items.length); // 3
const newItem = document.createElement('div');
newItem.className = 'item';
document.body.appendChild(newItem);
console.log(items.length); // 4 (تحدث مباشرة)
-
المجموعة الثابتة (NodeList) لا تتغير تلقائياً:
javascriptconst nodes = document.querySelectorAll('.item');
console.log(nodes.length); // 3
const newItem = document.createElement('div');
newItem.className = 'item';
document.body.appendChild(newItem);
console.log(nodes.length); // 3 (ثابتة حتى إعادة البحث)
الأداء والفعالية
على الرغم من أن getElementById هو الأسرع بشكل كبير بسبب بساطة البحث عن معرف فريد، فإن querySelector وquerySelectorAll توفران مرونة لا تضاهى في اختيار العناصر باستخدام محددات CSS معقدة، مما يجعلها أدوات مفضلة في تطوير الواجهات الحديثة.
لكن يجب الحذر من الإفراط في استخدام querySelectorAll بكثرة داخل حلقات أو عمليات متكررة لأنها قد تؤثر سلباً على أداء الصفحة، خاصة إذا كانت صفحة تحتوي على آلاف العناصر.
أفضل الممارسات لاستخدام دوال البحث في DOM
-
استخدم
getElementByIdعند البحث عن عنصر وحيد معرف بشكل فريد، لتوفير الأداء. -
استخدم
getElementsByClassNameأوgetElementsByTagNameعند التعامل مع مجموعات كبيرة من العناصر المتشابهة، خاصة إذا كنت تحتاج إلى أن تتفاعل مع التغييرات الحية في DOM. -
عند الحاجة إلى استعلامات معقدة أو متداخلة، استخدم
querySelectorأوquerySelectorAllمع محددات CSS مناسبة. -
تجنب استدعاء دوال البحث بشكل متكرر داخل حلقات إذا كان بالإمكان تخزين النتائج مؤقتًا، لتحسين الأداء.
-
كن واعياً لأن
getElementsByClassNameوgetElementsByTagNameتُرجع مجموعات حية، وهذا قد يؤثر على التكرار إذا قمت بتعديل DOM أثناء التكرار. -
استغل قوة محددات CSS في
querySelectorلزيادة دقة البحث وتقليل الحاجة إلى تنفيذ عمليات بحث متعددة.
حالات استخدام متقدمة مع querySelector
يمكن الاستفادة من querySelector في حالات متعددة معقدة تشمل:
-
اختيار عنصر بناءً على صفاته، مثلاً عنصر
الذي يحمل صفةtype="text":
javascriptconst textInput = document.querySelector('input[type="text"]');
-
البحث داخل عنصر معين فقط (scope):
javascriptconst container = document.getElementById('container');
const firstButton = container.querySelector('button');
-
اختيار العنصر الذي يحتوي على نص معين عبر تحديد الصفات:
javascriptconst activeLinks = document.querySelectorAll('a.active[href^="https"]');
التعامل مع مجموعات العناصر المسترجعة
التكرار
-
عند استخدام
getElementsByClassNameأوgetElementsByTagNameيتم الحصول على HTMLCollection، والذي يمكن التكرار عليه بواسطةforأوfor...ofفي المتصفحات الحديثة، ولكن لا تدعم جميع المتصفحات الحديثة استخدام دوال مثلforEachمباشرة على HTMLCollection. -
بينما
querySelectorAllيعيد NodeList، الذي يدعمforEachمباشرة.
تحويل المجموعات إلى مصفوفات
في بعض الحالات نحتاج إلى تحويل المجموعات إلى مصفوفات لتطبيق دوال مثل map أو filter:
javascriptconst nodes = document.querySelectorAll('.item');
const nodesArray = Array.from(nodes);
const filtered = nodesArray.filter(node => node.textContent.includes('نص معين'));
التعامل مع التوافق والمتصفحات
جميع الدوال المذكورة مدعومة بشكل واسع في جميع المتصفحات الحديثة، بما فيها Chrome وFirefox وEdge وSafari. ومع ذلك، قبل سنوات، كانت هناك فروقات طفيفة في دعم querySelector و querySelectorAll في المتصفحات القديمة، ولكن حالياً هذه الدوال أصبحت معياراً أساسياً لا غنى عنه في تطوير الويب الحديث.
الخلاصة
البحث في DOM باستخدام دوال getElement و querySelector يمثل جوهر التفاعل مع صفحات الويب في جافاسكربت. لكل طريقة مزاياها واستخداماتها، ويجب على المطور اختيار الأنسب منها حسب الحاجة، سواء كانت سرعة الأداء، مرونة الاستعلام، أو التعامل مع مجموعات العناصر.
-
getElementByIdيوفر أسرع طريقة للوصول إلى عنصر معرف. -
getElementsByClassNameوgetElementsByTagNameتعطي مجموعات حية لعناصر متشابهة. -
querySelectorوquerySelectorAllتمنح المرونة والقدرة على استعلام دقيق باستخدام محددات CSS معقدة.
مع التقدم في تطوير التطبيقات والواجهات، تبقى هذه الدوال أدوات أساسية لا يمكن الاستغناء عنها لضمان الوصول السهل، التفاعل الديناميكي، وتحقيق أفضل تجربة مستخدم عبر الويب.
المصادر والمراجع
-
MDN Web Docs – Document.querySelector(): https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
-
MDN Web Docs – Document.getElementById(): https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById

